package org.eae.eldf.framework.security.filter;

import java.io.IOException;
import java.util.Locale;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.ThreadContext;
import org.eae.eldf.entity.sys.Authorization;
import org.eae.eldf.framework.spring.SpringSecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

public class MySecurityFilter extends AbstractSecurityInterceptor implements
		Filter {
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	// 与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应，  
    // 其他的两个组件，已经在AbstractSecurityInterceptor定义  
    private FilterInvocationSecurityMetadataSource securityMetadataSource; 

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		
		 HttpServletRequest servletRequest=(HttpServletRequest)request;
		 HttpServletResponse servletResponse=(HttpServletResponse)response;
		 Authorization authorization =  SpringSecurityUtils.getCurrentUser();
		 if (authorization == null) {
				if ((servletRequest.getHeader("x-requested-with") != null && servletRequest
						.getHeader("x-requested-with").equalsIgnoreCase(
								"XMLHttpRequest"))) {
					servletResponse.setContentType("text/plain;charset=UTF-8");
					servletResponse.sendRedirect(servletRequest.getContextPath()+"/login.htm");
					return;
				}else{
					servletResponse.sendRedirect(servletRequest.getContextPath()+"/login.htm");
					return;
				}
			}
		 	
			Locale locale = (Locale) servletRequest.getSession().getAttribute(
					SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);
			if (locale == null) {
				locale = servletRequest.getLocale();
			}
			if(StringUtils.isNotBlank(servletRequest.getParameter("request_locale"))){
				String loc = servletRequest.getParameter("request_locale");
				if("zh".equals(loc)){
					Locale l = new Locale("zh", "CN"); 
					servletRequest.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,l);
				}else if("en".equals(loc)){
					Locale l = new Locale("en", "US"); 
					servletRequest.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,l);
				}else{
					servletRequest.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,LocaleContextHolder.getLocale());
				}
				
			}
			
			
			// 判断是否是刚登陆，或者是更换过用户登录
			Authorization userInfo = (Authorization)servletRequest.getSession().getAttribute(Authorization.AUTHORIZATION_KEY);
			if(userInfo == null||!authorization.getOperatorID().equals(userInfo.getOperatorID())){
				logger.debug("User logon, need to refresh userinfo in session with username: "
						+ authorization.getUsername());
				
				
				servletRequest.getSession().setAttribute(Authorization.AUTHORIZATION_KEY, authorization);
				
				userInfo = authorization;
			}
			servletRequest.getSession().setAttribute("WW_TRANS_I18N_LOCALE_LANGUAGE", locale);
			// 设置浏览器Locale
			userInfo.setPreferredLocale(locale);
			authorization.setPreferredLocale(locale);
			// put properties to log4j MDC.
			ThreadContext.put("userName", "[" + userInfo.getUsername() + "]");
			ThreadContext.put("clientIP", "[" + request.getRemoteAddr() + "]");
			ThreadContext.put("Locale", "[" + locale + "]");
			
			FilterInvocation fi = new FilterInvocation(request, response, chain);
			invoke(fi);

	}
	
	 private void invoke(FilterInvocation fi) throws IOException,  
     ServletException {  
		 logger.info("[MySecurityFilter] 用户发送请求！");  
		 
		 InterceptorStatusToken token = null;  
		 token = super.beforeInvocation(fi);  
		 try {  
		     fi.getChain().doFilter(fi.getRequest(), fi.getResponse());  
		 } finally {  
		     super.afterInvocation(token, null);  
		 }  
	 } 

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub

	}

	@Override
	public Class<?> getSecureObjectClass() {
		// TODO Auto-generated method stub
		// 下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误  
        return FilterInvocation.class;  
	}

	@Override
	public SecurityMetadataSource obtainSecurityMetadataSource() {
		// TODO Auto-generated method stub
		return this.securityMetadataSource;  
	}
	
	public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {  
        return securityMetadataSource;  
    } 
	
	public void setSecurityMetadataSource(  
            FilterInvocationSecurityMetadataSource securityMetadataSource) {  
        this.securityMetadataSource = securityMetadataSource;  
    } 

}
